﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using SacNetUG.Models;

namespace SacNetUG.Helpers
{
    public static class HtmlHelpers
    {
        public static readonly string CkEditor_js = Url("~/CkEditor/ckeditor.js");
        public static readonly string SacNetUg_js = Url("~/Scripts/SacNetUg.js");

        public static MvcHtmlString ValidatedEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                          Expression<Func<TModel, TProperty>> expression)
        {
            string html = "<tr><td>" + htmlHelper.LabelFor(expression) + "</td><td>" +
                          htmlHelper.EditorFor(expression) +
                          htmlHelper.ValidationMessageFor(expression) + "</td></tr>\r\n";

            return MvcHtmlString.Create(html);
        }

        public static MvcHtmlString NumericEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                        Expression<Func<TModel, TProperty>> expression)
        {
            string html = "<tr><td>" + htmlHelper.LabelFor(expression) + "</td><td>" +
                          //htmlHelper.EditorFor(expression, new { @class="numeric"}) +
                          htmlHelper.ValidationMessageFor(expression) + "</td></tr>\r\n";

            return MvcHtmlString.Create(html);
        }

        public static MvcHtmlString ValidatedCkEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                            Expression<Func<TModel, TProperty>>
                                                                                expression)
        {
            string html = "<tr><td>" + htmlHelper.LabelFor(expression) + "</td><td>" +
                          htmlHelper.CkEditorFor(expression) +
                          htmlHelper.ValidationMessageFor(expression) + "</td></tr>\r\n";

            return MvcHtmlString.Create(html);
        }

        public static MvcHtmlString CkEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                   Expression<Func<TModel, TProperty>> expression)
        {
            return htmlHelper.TextAreaFor(expression, new {@class = "guiEditor"});
        }

        //TODO convert strings to strongly typed whatzamahowzits
        public static MvcHtmlString NullableDropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
                                                                               Expression<Func<TModel, TProperty>>
                                                                                   expression,
                                                                               string tableName, string dataValueField,
                                                                               string dataTextField, bool insertBlank)
        {
            //get the list of items
            var db = new SacNetUGDataContext();
            Type type = db.GetType();
            PropertyInfo prop = type.GetProperty(tableName);
            if (prop == null)
                throw new ArgumentException(string.Format("{0} does not exist in database", tableName));

            var items = new List<SelectListItem>();
            if (insertBlank)
                items.Add(new SelectListItem {Text = "", Value = ""});

            var listItems = (IEnumerable) prop.GetValue(db, null);

            items.AddRange(new SelectList(listItems, dataValueField, dataTextField, expression));

            return expression == null
                       ? htmlHelper.DropDownListFor(p => 0, items)
                       : htmlHelper.DropDownListFor(expression, items);
        }

        public static MvcHtmlString SponsorCategoryDropDown<TModel>(this HtmlHelper<TModel> htmlHelper,
                                                                    int selectedValue)
        {
            var db = new SacNetUGDataContext();
            return htmlHelper.DropDownList("SponsorCategoryId",
                                           new SelectList(db.SponsorCategories.OrderBy(m => m.SortOrder), "Id", "Name",
                                                          selectedValue));
        }

        public static String UserTable(this HtmlHelper helper, List<TempUserView> userView)
        {
            //TODO:Refactor this into something resuable/generic with parameters for columns and rows
            int columns = 5;
            int rows = 0;
            if (userView.Count > 4)
                rows = 5;
            else
                rows = userView.Count;


            int currentRow = 0;
            int currentColumn = 0;
            int totalCount = 0;
            //TODO put this function in view, call with parameters. 
            //const string onClick = "onclick=\"Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), { insertionMode: Sys.Mvc.InsertionMode.replace, updateTargetId: 'userDetails', onSuccess: Function.createDelegate(this, showUserEdit) });\"";
            //string onClick = string.Format("onclick=\"userLinkClick({0})\"",user;
            //userLinkClick
            var sb = new StringBuilder();
            sb.Append("<table>");
            while (currentRow < rows && totalCount < userView.Count)
            {
                currentRow++;
                sb.Append("<tr>");
                currentColumn = 0;
                while (currentColumn < columns && totalCount < userView.Count)
                {
                    totalCount++;
                    currentColumn++;
                    int index = currentRow + ((currentColumn - 1)*columns) - 1;

                    if (index + 1 > userView.Count)
                    {
                        totalCount--;
                        sb.Append("<td>&nbsp;</td>");
                    }
                    else
                        //TempUserView user = ;
                    {
                        TempUserView user = userView[currentRow + ((currentColumn - 1)*columns) - 1];
                        //sb.AppendFormat("<td><a href='#' onclick=\"userLinkClick({0}, '{1}')\">{1}</a></td>", user.userid, user.name);
                        sb.AppendFormat("<td><a href='Create_EnterDetails/{0}'>{1}</a></td>", user.userid, user.name);
                    }


                    //if (user == null)
                    //{
                    //    sb.Append("<td>&nbsp;</td>");
                    //}
                    //else
                    //{

                    //}
                }
                sb.Append("</tr>");
            }
            sb.Append("</table>");

            return sb.ToString();
        }

        public static String TeamUserFields(this HtmlHelper helper, TeamUserViewModel tvm)
        {
            return null;
        }

        public static bool HasFile(this HttpPostedFileBase file)
        {
            return (file != null && file.ContentLength > 0) ? true : false;
        }

        public static string Image(this HtmlHelper helper, string url, string altText)
        {
            //TagBuilder builder = new TagBuilder("image");
            //builder.Attributes.Add("src", url);
            //builder.Attributes.Add("alt", altText);
            //builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            //return builder.ToString(TagRenderMode.SelfClosing);
            return Image(helper, url, altText, null);
        }

        public static string Image(this HtmlHelper helper, string url, string altText, object htmlAttributes)
        {
            var builder = new TagBuilder("image");
            builder.Attributes.Add("src", url);
            builder.Attributes.Add("alt", altText);
            if (htmlAttributes != null)
            {
                builder.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            }
            return builder.ToString(TagRenderMode.SelfClosing);
        }

        public static MvcHtmlString DonateButton(this HtmlHelper helper)
        {
            var sb = new StringBuilder();
            sb.Append("<form action='https://www.paypal.com/cgi-bin/webscr' method='post'>");
            sb.Append(helper.Hidden("cmd", "_donations"));
            sb.Append(helper.Hidden("business", "sacdnug@sacdotnet.org"));
            sb.Append(helper.Hidden("lc", "US"));
            sb.Append(helper.Hidden("item_name", "Sacramento DotNet User Group"));
            sb.Append(helper.Hidden("currency_code", "USD"));
            sb.Append(helper.Hidden("bn", "PP-DonationsBF:btn_donateCC_LG.gif:NonHostedGuest"));
            sb.Append(helper.Hidden("image_url", "http://www.sacnetug.org/images/SacDnug.gif"));
            sb.Append(helper.Hidden("return", "http://www.sacnetug.org"));
            sb.Append(
                "<input type='image' src='https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif' border='0' name='submit' alt='PayPal - The safer, easier way to pay online!' />");
            //sb.Append(helper.Image("", "https://www.paypal.com/en_US/i/scr/pixel.gif", 
            //    new {border = "0", width = "1", height = "1"}));
            sb.Append("</form>");

            return MvcHtmlString.Create(sb.ToString());
        }

        public static MvcHtmlString SpeakerLine(this HtmlHelper helper, Event thisEvent)
        {
            if (thisEvent.EventPresenters.Count == 0)
            {
                return MvcHtmlString.Create("<span class='bold'>Speaker</span>: None");
            }
            if (thisEvent.EventPresenters.Count == 1)
            {
                return
                    MvcHtmlString.Create(string.Format("<span class='bold'>Speaker:</span> {0}",
                                                       thisEvent.EventPresenters.FirstOrDefault().User.Name));
            }

            string speakers = "";
            foreach (EventPresenter presenter in thisEvent.EventPresenters)
            {
                if (speakers != "")
                {
                    //TODO: handle more than 2 speakers with commas
                    speakers += " & ";
                }
                speakers += presenter.User.Name;
            }
            //Don't like this presentation concern here
            return MvcHtmlString.Create(string.Format("<span class='bold'>Speakers:</span> {0}", speakers));
        }

        public static MvcHtmlString InlineSponsorImage(this HtmlHelper helper, Event thisEvent)
        {
            if (thisEvent.EventSponsors.Count == 0)
            {
                return MvcHtmlString.Create("");
            }

            StringBuilder sb = new StringBuilder();

            foreach (EventSponsor sponsor in thisEvent.EventSponsors)
            {
                if (sb.Length > 0)
                {
                    sb.AppendLine("<br />");
                    sb.AppendLine("<br />");
                }
                string image = helper.Image(sponsor.Sponsor.LogoUrl, sponsor.Sponsor.Name, new { @class = "imgRight smallULMargin" });
                if (string.IsNullOrEmpty(sponsor.Sponsor.Url))
                {
                    sb.AppendLine(image);
                }
                else
                {
                    //TODO: Replace with html.Anchor function after it is tested
                    var tb = new TagBuilder("a");
                    tb.Attributes.Add("href", sponsor.Sponsor.Url);
                    tb.Attributes.Add("target", "_blank");
                    tb.InnerHtml = image;
                    sb.AppendLine(tb.ToString());
                }

                
            }
            return MvcHtmlString.Create(sb.ToString());
            
            
            //EventSponsor sponsor = thisEvent.EventSponsors.FirstOrDefault();
            
            //if (sponsor == null)
            //{
            //    return MvcHtmlString.Create("");
            //}
            //string image = helper.Image(sponsor.Sponsor.LogoUrl, sponsor.Sponsor.Name, new {@class = "imgRight"});
            //if (string.IsNullOrEmpty(sponsor.Sponsor.Url))
            //{
            //    return MvcHtmlString.Create(image);
            //}
            ////TODO: Replace with html.Anchor function after it is tested
            //var tb = new TagBuilder("a");
            //tb.Attributes.Add("href", sponsor.Sponsor.Url);
            //tb.Attributes.Add("target", "_blank");
            //tb.InnerHtml = image;
            //return MvcHtmlString.Create(tb.ToString());
        }

        public static string Anchor(this HtmlHelper helper, string url, string innerHtml, string target)
        {
            var tb = new TagBuilder("a");
            tb.Attributes.Add("href", url);
            if (!string.IsNullOrEmpty(target))
                tb.Attributes.Add("target", "target");
            tb.InnerHtml = innerHtml;
            return tb.ToString();
        }

        public static MvcHtmlString AppId(this HtmlHelper helper)
        {
            var wll = new WindowsLiveLogin(true);
            return MvcHtmlString.Create(wll.AppId);
        }

        public static MvcHtmlString GetUserName(this HtmlHelper helper, string authId)
        {
            var repository = new SacNetUGRepository();
            var user = repository.GetUser(authId);
            if(user == null)
                return MvcHtmlString.Create("");

            return MvcHtmlString.Create(user.Name);
        }

        public static string Url(string fileName)
        {
            return T4MVCHelpers.ProcessVirtualPath(fileName);
        }

        public static MvcHtmlString RenderSponsorImages(this HtmlHelper helper, int columns,
                                                        IEnumerable<Sponsor> sponsors, int sponsorCategoryId)
        {
            var sb = new StringBuilder();
            int count = 0;
            foreach (
                Sponsor sponsor in
                    sponsors.Where(s => s.SponsorCategoryId == sponsorCategoryId).OrderBy(o => o.SortOrder))
            {
                if (count == 0)
                    sb.AppendLine("<tr>");
                sb.AppendLine("<td>");
                sb.AppendLine(helper.Anchor(sponsor.Url, helper.Image(sponsor.LogoUrl, sponsor.Name), "_blank"));
                sb.AppendLine("</td>");
                count += 1;
                if (count == columns)
                {
                    count = 0;
                    sb.AppendLine("</tr>");
                }
            }
            if (count != 0)
                sb.AppendLine("</tr>");
            return MvcHtmlString.Create(sb.ToString());
        }

        public static MvcHtmlString SponsorCategoryName(this HtmlHelper helper, int sponsorTypeId)
        {
            var db = new SacNetUGDataContext();
            IQueryable<string> name =
                db.SponsorCategories.Where(sc => sc.SponsorCategoryId == sponsorTypeId).Select(x => x.Name);
            return MvcHtmlString.Create(name.FirstOrDefault());
        }

        public static MvcHtmlString TimeSelector(this HtmlHelper helper, string namePrefix, string selectedHour, string selectedMinute)
        {
            var hours = new List<SelectListItem>();
            for (int i = 1; i < 13; i++)
            {

                hours.Add(new SelectListItem { Text = i.ToString(), Value = i.ToString(), Selected = i.ToString() == selectedHour ? true : false });
            }

            var minutes = new List<SelectListItem>();

            minutes.Add(new SelectListItem { Text = ":00", Value = "0", Selected = selectedMinute == ":00" ? true : false });
            minutes.Add(new SelectListItem { Text = ":15", Value = "15", Selected = selectedMinute == ":15" ? true : false });
            minutes.Add(new SelectListItem { Text = ":30", Value = "30", Selected = selectedMinute == ":30" ? true : false });
            minutes.Add(new SelectListItem { Text = ":45", Value = "45", Selected = selectedMinute == ":45" ? true : false });
            

            var amPm = new List<SelectListItem>();
            amPm.Add(new SelectListItem { Text = "AM", Value = "AM" });
            amPm.Add(new SelectListItem { Text = "PM", Value = "PM", Selected = true });

            StringBuilder sb = new StringBuilder();
            sb.Append(helper.DropDownList(namePrefix + "Hours", hours).ToString());
            sb.Append(helper.DropDownList(namePrefix + "Minutes", minutes).ToString());
            sb.Append(helper.DropDownList(namePrefix + "AmPm", amPm).ToString());

            return MvcHtmlString.Create(sb.ToString());
            
            
        }
    }

    public static class AddOns
    {
        public static void AddOrReplace(this TempDataDictionary dictionary, string key, object value)
        {
            if (dictionary.ContainsKey(key))
            {
                dictionary[key] = value;
            }
            else
            {
                dictionary.Add(key, value);
            }
        }

        public static void AddOrReplace(this IDictionary dictionary, string key, object value)
        {
            if (dictionary.Contains(key))
            {
                dictionary[key] = value;
            }
            else
            {
                dictionary.Add(key, value);
            }
        }
    }
}